package com.jp.knowledge.fragment;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

import com.bigkoo.quicksidebar.QuickSideBarTipsView;
import com.bigkoo.quicksidebar.QuickSideBarView;
import com.bigkoo.quicksidebar.listener.OnQuickSideBarTouchListener;
import com.google.gson.JsonObject;
import com.jiayen.cache.FileCacheManager;
import com.jiayen.util.ToasUtil;
import com.jp.knowledge.R;
import com.jp.knowledge.activity.BaseFragment;
import com.jp.knowledge.adapter.OnItemListerner;
import com.jp.knowledge.adapter.team_circle.TeamCircleConstactsAdapter;
import com.jp.knowledge.dialog.CommDialog;
import com.jp.knowledge.dialog.SelectDialog;
import com.jp.knowledge.http.HttpHelper;
import com.jp.knowledge.model.IModel;
import com.jp.knowledge.model.TeamCircleConstactsModel;
import com.jp.knowledge.model.UserData;
import com.jp.knowledge.my.adapter.CompanyContactsAdapter;
import com.jp.knowledge.my.model.OrganizaModel;
import com.jp.knowledge.my.util.MyUtil;
import com.jp.knowledge.my.util.PinyinComparator;
import com.jp.knowledge.util.ResultSubscriber;
import com.timehop.stickyheadersrecyclerview.StickyRecyclerHeadersDecoration;

import org.xutils.view.annotation.ViewInject;
import org.xutils.x;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import pl.droidsonroids.gif.GifImageView;
import rx.Observable;
import rx.Observer;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

public class ConstactsFragment extends BaseFragment implements ResultSubscriber.OnResultListener, View.OnClickListener {

	private static final int GET_CONSTACTS_CODE = 0x01;
	private static final int SET_COMPANY_MANAGER_CODE = 0x02;
	private static final int TRANSFER_SUPER_MANAGER_CODE = 0x03;
	private static final int REMOVE_USER_CODE = 0x04;

	private View contentView;
	@ViewInject(R.id.team_circle_contacts_edit_search)
	private EditText constactEdit;
	@ViewInject(R.id.team_circle_contacts_iv_clear)
	private ImageView constactEditClear;
	@ViewInject(R.id.loading_bg)
	private GifImageView loadingView;
	@ViewInject(R.id.team_circle_contacts_rv)
	private RecyclerView constactsListRv;
	@ViewInject(R.id.team_circle_contacts_sbv)
	private QuickSideBarView sideBarSbv;
	@ViewInject(R.id.team_circle_contacts_btv)
	private QuickSideBarTipsView sideBarBtv;

	private List<TeamCircleConstactsModel> allConstactsData;
	private List<TeamCircleConstactsModel> constactsListData;
	private TeamCircleConstactsAdapter constactsAdapter;
	private LinearLayoutManager constactsListLayoutManager;
	private List<String> letters;

	private UserData userData;
	private OrganizaModel company;
	private String paramId;

	private CommDialog generalUserDialog;
	private SelectDialog vipUserDialog;
	private CommDialog removeUserDialog;
	private CommDialog remindDialog;

	private String cachePath;
	private FileCacheManager cacheManager;

	public ConstactsFragment newInstance(OrganizaModel company) {
		this.company = company;
		this.paramId = company.getCompanyType() == 2 ? company.getClassId() : company.getCompanyId();
		return this;
	}

	@Nullable
	@Override
	public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
		if (contentView == null) {
			contentView = View.inflate(mContext, R.layout.fragment_constacts, null);
			x.view().inject(this, contentView);
			initData();
			initDialog();
			initOther();
			readCache();
		}
		return contentView;
	}

	private void initData() {
		userData = application.getUserData();
		allConstactsData = new ArrayList<>();
		constactsListData = new ArrayList<>();
		cachePath = mContext.getCacheDir().getPath() + "/constacts_" + paramId + ".dat";
		cacheManager = new FileCacheManager();
	}

	private void initDialog() {
		generalUserDialog = new CommDialog(mContext);
		generalUserDialog.setTag(0);
		generalUserDialog.setRight("呼叫");
		generalUserDialog.setRightListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				int position = (int) generalUserDialog.getTag();
				callPhone(constactsListData.get(position).getPhone());
			}
		});
		vipUserDialog = new SelectDialog(mContext);
		generalUserDialog.setTag(0);
		vipUserDialog.visibleTitle(false);
		vipUserDialog.addItem("拨打电话");
		vipUserDialog.addItem("设为管理员");
		vipUserDialog.addItem("转让超级管理员给他");
		vipUserDialog.addItem("强制退出组织");
		vipUserDialog.setOnDialogItemClickListener(new SelectDialog.OnSelectDialogItemClickListener() {
			@Override
			public void onSelectItemClick(int position) {
				TeamCircleConstactsModel constactsModel = constactsListData.get((int) vipUserDialog.getTag());
				switch (position) {
					case 0:         // 拨号
						callPhone(constactsModel.getPhone());
						break;
					case 1:         // 设为管理员
						remindDialog.setContent(constactsModel.getCompanyManage() != 1 ? "确定设为管理员？" : "是否取消管理员？");
						remindDialog.setTag(0);
						remindDialog.show();
						break;
					case 2:         // 转让超级管理员权限给他
						remindDialog.setContent("确定转让超级管理员身份？");
						remindDialog.setTag(1);
						remindDialog.show();
						break;
					case 3:         // 强制退出组织
						removeUserDialog.setTag((int) vipUserDialog.getTag());
						removeUserDialog.setEditText("");
						removeUserDialog.show();
						break;
				}
			}
		});
		removeUserDialog = new CommDialog(mContext);
		removeUserDialog.setTag(0);
		removeUserDialog.setShowWithKeyword(true);
		removeUserDialog.setEditHint("请输入理由");
		removeUserDialog.setRightClickDismiss(false);
		removeUserDialog.setRightListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				int position = (int) removeUserDialog.getTag();
				if (removeUserDialog.getEditText().trim().length() == 0) {
					ToasUtil.toast(mContext, "请输入拒绝理由");
				} else {
					removeUserFromCompany(position, removeUserDialog.getEditText());
					removeUserDialog.dismiss();
				}
			}
		});
		remindDialog = new CommDialog(mContext);
		remindDialog.setRightListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				TeamCircleConstactsModel constactsModel = constactsListData.get((int) vipUserDialog.getTag());
				if((int) remindDialog.getTag() == 0)
					setCompanyManager((int) vipUserDialog.getTag(), constactsModel.getCompanyManage() != 1);
				else
					transferSuperManager((int) vipUserDialog.getTag());
			}
		});
	}

	private void initOther() {
		constactsAdapter = new CompanyContactsAdapter(mContext, constactsListData);
		constactsAdapter.setShowCheckBox(false);
		constactsAdapter.setOnItemListerner(new OnItemListerner() {
			@Override
			public void onItemClick(View view, int position) {
				TeamCircleConstactsModel constactsModel = constactsListData.get(position);
				if (userData.getUuid().equals(constactsModel.getUserId()))
					return;
				if (company.getCompanyAdmin() == 1) {
					if (constactsModel.getCompanyManage() == 1)
						vipUserDialog.changedItemText(1, "取消管理员");
					else
						vipUserDialog.changedItemText(1, "设为管理员");
					vipUserDialog.setTag(position);
					vipUserDialog.show();
				} else {
					String tel = constactsListData.get(position).getPhone();
					if (TextUtils.isEmpty(tel)) {
						ToasUtil.toast(mContext, "该职员未曾保留电话号码!");
						return;
					}
					generalUserDialog.setContent(tel);
					generalUserDialog.setTag(position);
					generalUserDialog.show();
				}
			}
		});

		constactsListRv.setHasFixedSize(true);
		constactsListLayoutManager = new LinearLayoutManager(mContext);
		constactsListRv.setLayoutManager(constactsListLayoutManager);
		StickyRecyclerHeadersDecoration headersDecor =
				new StickyRecyclerHeadersDecoration(constactsAdapter);
		constactsListRv.addItemDecoration(headersDecor);
		constactsListRv.setAdapter(constactsAdapter);
		constactsListRv.addOnScrollListener(new RecyclerView.OnScrollListener() {
			@Override
			public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
				if (Math.abs(dy) > 20)
					MyUtil.closeKeyword(mContext, constactEdit);
				if (movePosition < 0)
					return;
				int n = movePosition - constactsListLayoutManager.findFirstVisibleItemPosition();
				if (0 <= n && n < constactsListRv.getChildCount()) {
					int top = constactsListRv.getChildAt(n).getTop();
					constactsListRv.scrollBy(0, top);
				}
				movePosition = -1;
			}
		});
		constactEdit.setOnEditorActionListener(new TextView.OnEditorActionListener() {
			@Override
			public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
				if (actionId == EditorInfo.IME_ACTION_DONE) {
					MyUtil.closeKeyword(mContext, constactEdit);
				}
				return true;
			}
		});

		letters = Arrays.asList(getResources().getStringArray(R.array.constacts_letters));
		sideBarSbv.setLetters(letters);
		sideBarSbv.setOnQuickSideBarTouchListener(new OnQuickSideBarTouchListener() {
			@Override
			public void onLetterChanged(String letter, int position, float y) {
				MyUtil.closeKeyword(mContext, constactEdit);
				sideBarBtv.setText(letter, position, (sideBarSbv.getY() - sideBarBtv.getY()) + y - sideBarBtv.getWidth());
				letterChanged(letter, position, y);
			}
			@Override
			public void onLetterTouching(boolean touching) {
				sideBarBtv.setVisibility(touching ? View.VISIBLE : View.INVISIBLE);
			}
		});

		constactEditClear.setOnClickListener(this);
		constactEditClear.setVisibility(View.GONE);
		constactEdit.addTextChangedListener(new TextWatcher() {
			@Override
			public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
			@Override
			public void onTextChanged(CharSequence s, int start, int before, int count) {}
			@Override
			public void afterTextChanged(Editable s) {
				if (s.length() == 0 && constactEditClear.getVisibility() != View.GONE)
					constactEditClear.setVisibility(View.GONE);
				else if (s.length() != 0 && constactEditClear.getVisibility() != View.VISIBLE)
					constactEditClear.setVisibility(View.VISIBLE);
				editTextChange();
			}
		});
	}

	private void letterChanged(String letter, int position, float y) {
		for (int i = 0; i < constactsListData.size(); i++) {
			if (constactsListData.get(i).getRemark().charAt(0) == letters.get(position).charAt(0)) {
				moveToPosition(i);
				return;
			}
		}
	}

	private void editTextChange() {
		String searchStr = constactEdit.getText().toString().trim();
		constactsListData.clear();
		if (searchStr.length() == 0) {
			constactsListData.addAll(allConstactsData);
		} else {
			for (TeamCircleConstactsModel constactsModel : allConstactsData) {
				if ((constactsModel.getUserName() != null && constactsModel.getUserName().contains(searchStr))
						|| (constactsModel.getPhone() != null && constactsModel.getPhone().contains(searchStr)))
					constactsListData.add(constactsModel);
			}
		}
		constactsAdapter.updateAdapter(constactsListData);
	}

	private int movePosition = -1;
	private void moveToPosition(int position) {
		int firstItem = constactsListLayoutManager.findFirstVisibleItemPosition();
		int lastItem = constactsListLayoutManager.findLastVisibleItemPosition();
		if (position <= firstItem) {
			constactsListRv.scrollToPosition(position);
		} else if (position <= lastItem) {
			int top = constactsListRv.getChildAt(position - firstItem).getTop();
			constactsListRv.scrollBy(0, top);
		} else {
			constactsListRv.scrollToPosition(position);
			movePosition = position;
		}
	}

	// 获取通通讯录列表
	private void getData() {
		JsonObject param = new JsonObject();
		param.addProperty("token", HttpHelper.token);
		param.addProperty("type", company.getCompanyType());
		param.addProperty("id", paramId);
		HttpHelper.getInstance(mContext).companyAddressBook(param, GET_CONSTACTS_CODE, this);
	}

	/* 设置公司管理员 */
	private void setCompanyManager(int position, boolean isManager) {
		JsonObject param = new JsonObject();
		param.addProperty("type", company.getCompanyType());
		if (company.getCompanyType() == 2)
			param.addProperty("id", company.getClassId());
		else
			param.addProperty("id", company.getCompanyId());
		param.addProperty("userId", constactsListData.get(position).getUserId());
//        param.addProperty("recommendAction", isManager?1:0);
		param.addProperty("action", isManager ? 1 : 0);
		HttpHelper.getInstance(mContext).setCompanyManager(param, position * 10 + SET_COMPANY_MANAGER_CODE, this);
	}

	/* 转让超级管理员 */
	private void transferSuperManager(int position) {
		JsonObject param = new JsonObject();
		param.addProperty("type", company.getCompanyType());
		if (company.getCompanyType() == 2)
			param.addProperty("id", company.getClassId());
		else
			param.addProperty("id", company.getCompanyId());
		param.addProperty("userId", constactsListData.get(position).getUserId());
		HttpHelper.getInstance(mContext).transferSuperManager(param, position * 10 + TRANSFER_SUPER_MANAGER_CODE, this);
	}

	/* 使用户强制退出组织 */
	private void removeUserFromCompany(int position, String reason) {
		JsonObject param = new JsonObject();
		param.addProperty("type", company.getCompanyType());
		if (company.getCompanyType() == 2)
			param.addProperty("id", company.getClassId());
		else
			param.addProperty("id", company.getCompanyId());
		param.addProperty("userId", constactsListData.get(position).getUserId());
		param.addProperty("reason", reason);
		HttpHelper.getInstance(mContext).removeUserFromCompany(param, position * 10 + REMOVE_USER_CODE, this);
	}

	private void callPhone(String phone) {
		if (TextUtils.isEmpty(phone)) {
			ToasUtil.toast(mContext, "该职员未曾保留电话号码!");
		} else {
			Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phone));
			intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			startActivity(intent);
		}
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
			case R.id.icon_left:
				getActivity().onBackPressed();
				break;
			case R.id.team_circle_contacts_iv_clear:
				constactEdit.setText("");
				break;
		}
	}

	@Override
	public void onStart(int requestType) {
		if (requestType == GET_CONSTACTS_CODE && constactsAdapter.getItemCount() == 0) {
			loadingView.setVisibility(View.VISIBLE);
			constactsListRv.setVisibility(View.GONE);
			sideBarBtv.setVisibility(View.GONE);
			sideBarSbv.setVisibility(View.GONE);
		} else if (requestType != GET_CONSTACTS_CODE){
			loadingDialog.show();
		}
	}

	@Override
	public void onCompleted(int requestType) {
		if (requestType == GET_CONSTACTS_CODE) {
			loadingView.setVisibility(View.GONE);
			constactsListRv.setVisibility(View.VISIBLE);
			sideBarBtv.setVisibility(View.VISIBLE);
			sideBarSbv.setVisibility(View.VISIBLE);
		} else {
			loadingDialog.cancel();
		}
	}

	@Override
	public void onError(int requestType) {
		onCompleted(requestType);
	}

	@Override
	public void onNext(IModel data, int requestType) {
		if (data.getErrcode() != 0) {
			ToasUtil.toast(mContext, data.getMessage());
			onError(requestType);
		} else if (requestType == GET_CONSTACTS_CODE) {
			allConstactsData = data.getList(TeamCircleConstactsModel.class);
			if(allConstactsData == null)
				allConstactsData = new ArrayList<>();
			updateView();
			saveCache(cachePath, allConstactsData);
		} else if (requestType % 10 == SET_COMPANY_MANAGER_CODE) {          // 设为管理员
			TeamCircleConstactsModel constactsModel = constactsListData.get(requestType / 10);
			constactsModel.setCompanyManage(constactsModel.getCompanyManage() == 1 ? 0 : 1);
			constactsAdapter.updateAdapter(constactsListData);
		} else if (requestType % 10 == TRANSFER_SUPER_MANAGER_CODE) {       // 转让超级管理员
			TeamCircleConstactsModel constactsModel = constactsListData.get(requestType / 10);
			constactsModel.setCompanyAdmin(1);
			company.setCompanyAdmin(0);
			for (TeamCircleConstactsModel model : constactsListData) {
				if (userData.getUuid().equals(model.getUserId())) {
					model.setCompanyAdmin(0);
					break;
				}
			}
			constactsAdapter.updateAdapter(constactsListData);
		} else if (requestType % 10 == REMOVE_USER_CODE) {                    // 强制退出组织
			constactsListData.remove(requestType / 10);
			constactsAdapter.updateAdapter(constactsListData);
		}
	}

	private void updateView(){
		for (TeamCircleConstactsModel model : allConstactsData) {
			String userName = model.getUserName();
			if (userName == null)
				userName = "";
			String remark = PinyinComparator.getPinyin(userName).toUpperCase();
			if (remark.length() == 0 || remark.charAt(0) < 'A' || remark.charAt(0) > 'Z')
				remark = '#' + remark;
			model.setRemark(remark);
		}
		constactsListData.clear();
		constactsListData.addAll(allConstactsData);
		constactsAdapter.updateAdapter(constactsListData);
	}

	private void readCache(){
		Observable.create(new Observable.OnSubscribe<List<TeamCircleConstactsModel>>() {
			@Override
			public void call(Subscriber<? super List<TeamCircleConstactsModel>> subscriber) {
				List<TeamCircleConstactsModel> data = (List<TeamCircleConstactsModel>) cacheManager.readObject(cachePath);
				subscriber.onNext(data);
				subscriber.onCompleted();
			}
		}).subscribeOn(Schedulers.io())
		.observeOn(AndroidSchedulers.mainThread())
		.subscribe(new Observer<List<TeamCircleConstactsModel>>() {
			@Override
			public void onCompleted() {
				getData();
			}
			@Override
			public void onError(Throwable e) {
				onCompleted();
			}
			@Override
			public void onNext(List<TeamCircleConstactsModel> data) {
				allConstactsData.clear();
				if(data != null && data.size() > 0)
					allConstactsData.addAll(data);
				updateView();
			}
		});
	}

	private void saveCache(final String cachePath, final Object data){
		new Thread(new Runnable() {
			@Override
			public void run() {
				cacheManager.wirteObject(data, cachePath);
			}
		}).start();
	}
}
